import codecs

import math
import config


# 纵向走向图
class unit1():
    def __init__(self, typename, startx, starty, cta, R, flag):
        self.type = typename
        self.startX = startx
        self.startY = starty
        self.cta = cta
        self.R = R
        self.flag = flag

    def getz(self, the_x):
        if self.type == 'circle':
            temp1 = the_x - self.startX - self.flag * self.R * math.sin(self.cta)
            temp2 = (-self.flag * math.tan(self.cta))
            temp2 = math.atan(temp2)
            temp3 = math.asin(temp1 / self.R)
            cta2 = temp3 - temp2
            xp = self.R * math.sin(cta2)
            yp = self.R * (1 - math.cos(cta2))
            Y = (self.startY + (xp * math.sin(self.cta) + (-self.flag) * yp * math.cos(self.cta)))
            return Y
        if self.type == 'line':
            Y = (self.startY + (the_x - self.startX) * math.tan(self.cta))
            return Y


def getk(x1, y1, x2, y2):
    if x2 == x1:
        return 0
    return (y2 - y1) / (x2 - x1)


def getdis(x1, y1, x2, y2):
    return math.sqrt(math.pow(y2 - y1, 2) + math.pow(x2 - x1, 2))


def Readfile(address):
    f = codecs.open(address, mode='r', encoding='utf-8')
    line = f.readline()  # 以行的形式进行读取文件
    x = []
    y = []
    r = []
    while line:
        a = line.split()
        b = a[0:1]
        x.append(float(b[0]))
        b = a[1:2]
        y.append(float(b[0]))
        b = a[2:3]
        r.append(float(b[0]))
        line = f.readline()
    f.close()
    return x, y, r


def get_the_route(x=None, y=None, r=None):
    if x is None or y is None or r is None:
        x, y, r = Readfile(config.section_value_path)
    units1 = []
    start = [x[0], y[0]]
    for i in range(1, 36):
        jd = [x[i], y[i]]
        end = [x[i + 1], y[i + 1]]
        R = r[i]
        k1 = getk(start[0], start[1], jd[0], jd[1])
        k2 = getk(jd[0], jd[1], end[0], end[1])
        if k2 > k1:
            flag1 = -1
        else:
            flag1 = 1
        dis1 = getdis(start[0], start[1], jd[0], jd[1])
        dis2 = getdis(jd[0], jd[1], end[0], end[1])
        dis3 = getdis(start[0], start[1], end[0], end[1])
        alafa = (math.pow(dis1, 2) + math.pow(dis2, 2) - math.pow(dis3, 2)) / (2 * dis1 * dis2)
        alafa = math.pi - math.acos(alafa)
        cta = math.atan(k1)
        T = R * math.tan(alafa / 2)
        start_circle = [jd[0] - T * math.cos(cta), jd[1] - T * math.sin(cta)]
        temp = unit1('line', start[0], start[1], cta, R, flag1)
        units1.append(temp)
        ly = R * alafa
        cta2 = (ly / R)
        xp = R * math.sin(cta2)
        yp = R * (1 - math.cos(cta2))
        XP = (start_circle[0] + (xp * math.cos(cta) + flag1 * yp * math.sin(cta)))
        YP = (start_circle[1] + (xp * math.sin(cta) + (-flag1) * yp * math.cos(cta)))
        temp = unit1('circle', start_circle[0], start_circle[1], cta, R, flag1)
        units1.append(temp)
        start = [XP, YP]
    return units1


units2_1 = get_the_route()  # 纵断面参数
units2_2 = get_the_route()  # 纵断面参数


def getZ(the_x,flag):
    if flag is 1:
        lo = units2_1[0]
        for i in units2_1:
            if i.startX <= the_x:
                lo = i
            else:
                break
        return lo.getz(the_x)
    else:
        lo = units2_2[0]
        for i in units2_2:
            if i.startX <= the_x:
                lo = i
            else:
                break
        return lo.getz(the_x)
